import {
  Button,
  Card,
  Dialog,
  Ellipsis,
  Form,
  Grid,
  Popup,
  ScrollBar,
  Swiper,
} from '@sei/suid-mobile';
import { AddCircleOutline, DeleteOutline } from '@sei/suid-mobile-icons';
import React, {
  createContext,
  useContext,
  useEffect,
  useRef,
  useState,
} from 'react';
import { useStore } from 'zustand';
import { ConfigContext, FRContext } from '../../models/context';
import { parseAllExpression } from '../../models/expression';
import { getWidget, isFunction } from '../../utils';
import './index.less';

const UpperContext = createContext(() => {});
const getParamValue =
  (formCtx: any, upperCtx: any, schema: any) => (valueKey: string) => {
    return schema[valueKey] ?? upperCtx[valueKey] ?? formCtx[valueKey];
  };

export default (props: any) => {
  const { schema: _schema, path, renderCore, rootPath: _rootPath } = props;

  const store: any = useContext(FRContext);
  const formCtx: any = useStore(store, (state: any) => state.context);
  const upperCtx: any = useContext(UpperContext);
  const { form, methods, widgets }: any = useContext(ConfigContext);

  const formData = form.getFieldsValue(true);
  const { schema: formSchema, isTableMode: tableMode } = store.getState();

  const { items, ...otherSchema } = _schema;
  const schema = {
    items,
    ...parseAllExpression(otherSchema, formData, _rootPath, formSchema),
  };

  // 检查是否使用表格模式
  const isTableMode = tableMode || schema.widget === 'table';
  let Widget = isTableMode ? getWidget(widgets, 'Table', schema) : null;

  const defaultValue = schema.default ?? (schema.defaultValue || []);
  const { defaultIndex = 0, onSaveCallBack } = tableMode || {};
  const [visible, setVisible] = useState(false);
  const [swiperIndex, setSwiperIndex] = useState(defaultIndex);
  const [fieldLength, setFieldLength] = useState<number>();
  const { onAdd, onRemove } = schema.props || {};
  const swiperRef = useRef<any>(null);

  const getValues = () => {
    const fieldValue = form.getFieldValue(path);
    // 过滤掉 undefined 、null、{} 值以获得准确的长度
    return Array.isArray(fieldValue)
      ? fieldValue.filter(
          (item) =>
            item !== undefined && item !== null && Object.keys(item).length > 0,
        )
      : [];
  };
  const getFieldsLength = () => {
    const fieldValue = getValues();
    return fieldValue.length;
  };

  useEffect(() => {
    const fieldsLength = getFieldsLength();
    setFieldLength(fieldsLength);
  }, []);

  const handleAdd = (add: any, data?: any) => {
    let addFunc = onAdd;
    if (typeof onAdd === 'string') {
      addFunc = methods[onAdd];
    }

    if (isFunction(addFunc)) {
      addFunc((funData?: any) => add(funData || data), { schema, data });
      return;
    }
    add(data || {});
    const fieldsLength = getFieldsLength();
    setFieldLength(fieldsLength);
  };

  const handleRemove = (remove: any, index: number) => {
    let removeFunc = onRemove;
    if (typeof onRemove === 'string') {
      removeFunc = methods[onRemove];
    }

    if (isFunction(removeFunc)) {
      removeFunc(() => remove(index), { schema, index });
      return;
    }

    // 直接调用删除函数
    remove(index);

    // 删除后跳转到上一项
    if (swiperRef.current && index > 0) {
      setTimeout(() => {
        swiperRef.current?.swipeTo(index - 1);
      }, 100);
    }

    const fieldsLength = getFieldsLength();
    setFieldLength(fieldsLength);
    if (fieldsLength === 0) {
      // 没有数据了，关闭滑动表单的弹窗
      setVisible(false);
    }
  };

  const getValueFromKey = getParamValue(formCtx, upperCtx, schema);

  const readOnly = getValueFromKey('readOnly');

  if (schema.hidden) {
    return null;
  }

  const preRootPath = [...(_rootPath || [])].splice(0, _rootPath.length - 1);
  const rootPath = [...preRootPath, ...path];

  // 创建一个可以直接删除指定索引的函数
  const removeItemByIndex = (index: number) => {
    // 获取当前表单中的数组值
    const currentArray = form.getFieldValue(path) || [];
    // 创建新的数组，移除指定索引的元素
    const newArray = [...currentArray];
    newArray.splice(index, 1);
    // 更新表单中的值
    form.setFieldValue(path, newArray);

    // 更新字段长度
    const fieldsLength = newArray.length;
    setFieldLength(fieldsLength);
  };

  // 实现点击表格某一行的编辑功能。先打开Popup,再根据行号设置Swiper的defaultIndex
  const editItemByIndex = (index: number) => {
    setSwiperIndex(index);
    setVisible(true);
  };

  // 实现在表格内点击添加，自动添加一行，并跳转到对应的表单
  const addItemByIndex = (index: number) => {
    // 获取当前path下的表单值
    const currentArray = form.getFieldValue(path) || [];

    // 在指定索引位置插入一个新项（空对象）
    const newArray = [...currentArray];
    newArray.splice(index, 0, {});

    // 更新表单中的值
    form.setFieldValue(path, newArray);

    // 更新字段长度
    const fieldsLength = newArray.length;
    setFieldLength(fieldsLength);

    // 设置swiper索引到新添加的项
    setSwiperIndex(index);

    // 显示弹窗
    setVisible(true);
  };

  const renderArrayFields = () => {
    return (
      <div className="frm-list-swipeMode">
        <Form.Array name={path} initialValue={defaultValue}>
          {(fields, operation) => {
            if (fields.length === 0) {
              return fields.map(({ index }) => {
                return renderCore({
                  schema,
                  parentPath: [index],
                  rootPath: [...rootPath, index],
                });
              });
            } else {
              return [
                <Swiper
                  key={`swiper-container-${swiperIndex}`}
                  className="swiper-container"
                  loop={false}
                  allowTouchMove={true}
                  ref={swiperRef}
                  indicator={(total, current) => {
                    if (readOnly) {
                      return (
                        <div className="customIndicator">
                          {`${current + 1} / ${total}`}
                        </div>
                      );
                    }
                    return null;
                  }}
                  total={!readOnly ? fields.length + 1 : fields.length}
                  onIndexChange={(index: number) => {
                    if (index === fields.length && !readOnly) {
                      handleAdd(operation.add);
                    }
                  }}
                  defaultIndex={swiperIndex}
                  style={{ '--border-radius': '8px', height: '100dvh' }}
                >
                  {fields.map((field, index) => (
                    <Swiper.Item
                      key={field.key || index}
                      className="frm-swiper-slide"
                      style={{ height: '100%' }}
                    >
                      <div style={{ margin: 12 }}>
                        <Card
                          style={{
                            '--border-radius': '0',
                            height: 'calc(100% - 70px)',
                            backgroundColor: 'white',
                            borderTopRightRadius: 8,
                            borderTopLeftRadius: 8,
                          }}
                          title={
                            <div
                              style={{
                                display: 'flex',
                                alignItems: 'flex-start',
                                flexDirection: 'column',
                                justifyContent: 'left',
                              }}
                            >
                              <div
                                style={{
                                  fontWeight: 600,
                                  fontSize: '18px',
                                }}
                              >
                                第{index + 1}行
                              </div>
                              <Ellipsis
                                style={{
                                  fontWeight: 400,
                                  fontSize: '14px',
                                }}
                                direction="end"
                                content={schema.title}
                              />
                            </div>
                          }
                          extra={
                            <>
                              {!readOnly && (
                                <DeleteOutline
                                  style={{ color: 'red', fontSize: '18px' }}
                                  onClick={() => {
                                    Dialog.confirm({
                                      content: '确定删除该项吗？',
                                      onConfirm: () => {
                                        handleRemove(operation.remove, index);
                                      },
                                    });
                                  }}
                                />
                              )}
                            </>
                          }
                        >
                          <ScrollBar>
                            {renderCore({
                              schema,
                              parentPath: [index],
                              rootPath: [...rootPath, index],
                            })}
                          </ScrollBar>
                        </Card>
                        <div
                          style={{
                            borderBottomRightRadius: '8px',
                            borderBottomLeftRadius: '8px',
                            backgroundColor: '#F7FBFC',
                            width: '100%',
                            display: 'flex',
                          }}
                        >
                          <Button
                            style={{
                              '--border-radius': '0',
                              flex: 1,
                            }}
                            color="primary"
                            fill="none"
                            onClick={() => {
                              swiperRef.current?.swipePrev();
                            }}
                          >
                            上一行
                          </Button>
                          <Button
                            style={{
                              '--border-radius': '0',
                              flex: 1,
                            }}
                            color="primary"
                            fill="none"
                            onClick={() => {
                              if (!readOnly) {
                                // 使用递归验证选项验证当前可见的字段
                                form
                                  .validateFields([], { recursive: true })
                                  .then((values) => {
                                    setVisible(false);
                                    onSaveCallBack?.(fields, values);
                                    // 验证通过后执行保存回调
                                  })
                                  .catch((error) => {
                                    const { values } = error;
                                    // console.log(" ~ -----(index.ts:357) ", JSON.stringify(error, null, 2));
                                    // 过滤掉errors为[""]的项
                                    const errorFields =
                                      error.errorFields.filter((item) => {
                                        // 检查errors数组中是否存在非空字符串 并且检查是否是空数组
                                        return (
                                          item.errors &&
                                          item.errors.some(
                                            (error) =>
                                              error && error.trim() !== '',
                                          )
                                        );
                                      });
                                    // 验证失败，显示错误信息弹窗
                                    // 过滤出当前数组路径下的错误
                                    const currentArrayPath = path.join('.');
                                    const errorMessages = errorFields
                                      .filter((field: any) => {
                                        // 检查错误字段是否属于当前数组路径下
                                        const fieldName = Array.isArray(
                                          field.name,
                                        )
                                          ? field.name.join('.')
                                          : field.name;
                                        return fieldName.startsWith(
                                          currentArrayPath,
                                        );
                                      })
                                      .map((field: any) => {
                                        // 获取数组索引信息
                                        let rowIndex = '';
                                        if (
                                          Array.isArray(field.name) &&
                                          field.name.length >= 2
                                        ) {
                                          const index =
                                            field.name[field.name.length - 2];
                                          if (!isNaN(Number(index))) {
                                            rowIndex = `第${
                                              Number(index) + 1
                                            }行 `;
                                          }
                                        }
                                        // 获取错误信息
                                        const fieldErrors =
                                          field.errors.join('\n');
                                        return `${rowIndex}${fieldErrors}`; // 返回带行号的错误信息
                                      });
                                    if (errorMessages.length > 0) {
                                      Dialog.alert({
                                        content: (
                                          <div>
                                            {errorMessages.map(
                                              (msg: string, index: number) => (
                                                <div
                                                  key={index}
                                                  style={{
                                                    marginBottom: '8px',
                                                  }}
                                                >
                                                  {msg
                                                    .split('\n')
                                                    .map(
                                                      (
                                                        line: string,
                                                        lineIndex: number,
                                                      ) => (
                                                        <div key={lineIndex}>
                                                          {line}
                                                        </div>
                                                      ),
                                                    )}
                                                </div>
                                              ),
                                            )}
                                          </div>
                                        ),
                                        confirmText: '确定',
                                      });
                                    } else {
                                      // 如果没有当前数组内的错误，则关闭弹窗
                                      setVisible(false);
                                      onSaveCallBack?.(fields, values);
                                    }
                                    // console.log(" ~ -----(index.ts) validation error", JSON.stringify(error, null, 2));
                                  });
                              } else {
                                setVisible(false);
                              }
                            }}
                          >
                            返回
                          </Button>
                          <Button
                            style={{
                              '--border-radius': '0',
                              flex: 1,
                            }}
                            color="primary"
                            fill="none"
                            onClick={() => {
                              swiperRef.current?.swipeNext();
                            }}
                          >
                            下一行
                          </Button>
                        </div>
                      </div>
                    </Swiper.Item>
                  ))}
                </Swiper>,
              ];
            }
          }}
        </Form.Array>
      </div>
    );
  };

  if (isTableMode) {
    // 获取当前字段的值
    const fieldValue = getValues();

    return (
      <>
        <div>
          <div style={{ display: 'none' }}>
            <Form.Array name={path} initialValue={defaultValue}>
              {() => []}
            </Form.Array>
          </div>
          <Widget
            schema={schema}
            addons={form}
            value={fieldValue}
            readOnly={readOnly}
            path={path}
            rootPath={rootPath}
            renderCore={renderCore}
            handleAdd={addItemByIndex}
            handleEdit={editItemByIndex}
            handleRemove={removeItemByIndex}
            setVisible={setVisible}
          />
        </div>

        <Popup position="bottom" visible={visible} style={{ height: '90%' }}>
          {renderArrayFields()}
        </Popup>
      </>
    );
  }

  return (
    <Grid.Item className="frm-list">
      <Form.Array
        name={path}
        initialValue={defaultValue}
        renderAdd={
          !readOnly && (!schema.max || fieldLength < schema.max)
            ? () => (
                <span>
                  <AddCircleOutline /> 添加
                </span>
              )
            : undefined
        }
        onAdd={({ add }) => handleAdd(add)}
        renderHeader={({ index }, { remove }) => (
          <>
            {schema.title && (
              <span>
                {schema.title} {index + 1}
              </span>
            )}
            {!readOnly && (!schema.min || fieldLength > schema.min) && (
              <a
                onClick={() => handleRemove(remove, index)}
                style={{ float: 'right' }}
              >
                删除
              </a>
            )}
          </>
        )}
      >
        {(fields) =>
          fields.map(({ index }) => {
            return renderCore({
              schema,
              parentPath: [index],
              rootPath: [...rootPath, index],
            });
          })
        }
      </Form.Array>
    </Grid.Item>
  );
};
